/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hormigas_packettracker.colonia;

import hormigas_packettracker.Heuristica;
import hormigas_packettracker.beans.Mapa;
import hormigas_packettracker.beans.Pedido;
import hormigas_packettracker.beans.Punto;
import hormigas_packettracker.beans.Vehiculo;
import hormigas_packettracker.config.GestorVehiculos;
import hormigas_packettracker.config.Parameters;
import hormigas_packettracker.config.Reloj;
import hormigas_packettracker.config.Solucion;
import java.util.ArrayList;

/**
 *
 * @author Shadow
 */
public class ColoniaHormigas {

    public static ArrayList<ArrayList<Nodo>> mejoresHormigas;
    public static MatrizFeromona feromonas;
    public static ArrayList<Nodo> ordenes = new ArrayList<>();
    public static ArrayList<Nodo> mapaNodos = new ArrayList<>();
    public static final float valorInicialFeromona = 1;
    public static final int numHormigas = 3;

    public static void initFeronoma() {
        feromonas = MatrizFeromona.getInstance(mapaNodos, valorInicialFeromona);
    }

    public static ArrayList<Hormiga> crearHormigas(int numHormigas, Vehiculo v) {
        ArrayList<Hormiga> list = new ArrayList<>();
        for (int i = 0; i < numHormigas; i++) {
            Hormiga newHormiga = new Hormiga(v);
            list.add((newHormiga));
        }
        return list;
    }

    public static void crearNodosMapa() {
        int nNodos = Mapa.getPuntos().size();
        for (int i = 0; i < nNodos; i++) {
            Punto p = Mapa.getPuntos().get(i);
            Nodo node = new Nodo(p);
            mapaNodos.add(node);
        }
    }

    public static void crearListaOrdenes(ArrayList<Pedido> pedidos) {
        for (Pedido pedido:pedidos) {
            Punto p = pedido.getDestino();
            Nodo n = mapaNodos.get(Mapa.getIndicePunto(p.getX(), p.getY()));
            n.setDemand(pedido.getDemanda());
            n.setVentanaTiempoAct(pedido.getPrioridad());
            n.setVentanaTiempoIni(pedido.getPrioridad());
            if (!ordenes.contains(n))
                ordenes.add(n);
        }
    }

    public static void actualizar(Hormiga hormiga) {
        int cap = hormiga.getCapacidadActual();
        int rSize = hormiga.getRoute().size();
        for (int i = 0; i < rSize; i++) {
            int dem = hormiga.getRoute().get(i).getDemand();
            if (cap >= dem) {
                hormiga.getRoute().get(i).setDemand(0);
                ordenes.remove(hormiga.getRoute().get(i));
            } else {
                hormiga.getRoute().get(i).setDemand(dem - cap);
            }
        }
    }

    public static void obtenerSolucion(ArrayList<Pedido> pedidos,ArrayList<Pedido> pedidosNuevos) {
        ordenes = new ArrayList<>();
        crearListaOrdenes(pedidos);
        ArrayList<Vehiculo> vehiculos = GestorVehiculos.getInstancia().getVehiculos();
        mejoresHormigas = new ArrayList<ArrayList<Nodo>>();
        //initializeArcsPheromoneLevel();//se puede resetear o tener algun valor residual
        int vSize = vehiculos.size();
        for (int n = 0; n < vSize; n++) {
            //variables para guardar la mejor solucion
            if (!vehiculos.get(n).disponible) {
                mejoresHormigas.add(new ArrayList<Nodo>());
                continue;
            }
            float bestCost = Float.POSITIVE_INFINITY;
            Hormiga mejorHormiga = null;
            //se crean las hormigas
            ArrayList<Hormiga> listaHormigas = crearHormigas(numHormigas, vehiculos.get(n));
            if (n == 0 && Reloj.getInstancia().getHora()==5 && Reloj.getInstancia().getMinuto()==48){
                int jjjj = 0;
            }
            for (int i = 0; i < listaHormigas.size(); i++) {
                //crear una lista temporal de las pedidos por cada hormiga
                ArrayList<Nodo> tempOrders = (ArrayList<Nodo>) ordenes.clone();
                Hormiga hormigaActual = listaHormigas.get(i);
                while (!hormigaActual.isDone()) {
                    hormigaActual.selectNextDestination(tempOrders, feromonas);
                    feromonas.updatePheromoneTrail(hormigaActual.getRoute());
                }
                //volver al almacen una vez que se acaba
                Punto almacenP = Mapa.getAlmacen();
                Nodo almacen = mapaNodos.get(Mapa.getIndicePunto(almacenP.getX(), almacenP.getY()));
                hormigaActual.getRoute().add(almacen);
                //de todas las hormigas cual tuvo el mejor costo
                float currentCost = hormigaActual.calculateCostoRuta();
                if (currentCost <= bestCost) {
                    bestCost = currentCost;
                    mejorHormiga = hormigaActual;
                }
            }
            actualizar(mejorHormiga);
            feromonas.actualizarMejorRastroFeromona(mejorHormiga.getRoute(), bestCost);
            mejoresHormigas.add(mejorHormiga.getRoute());
        }
    }
}
